package com.yupi.springbootinit.service.workflow;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yupi.springbootinit.mapper.*;
import com.yupi.springbootinit.messagecenter.MessageCenterProperties;
import com.yupi.springbootinit.model.entity.*;
import com.yupi.springbootinit.service.OutboxService;
import com.yupi.springbootinit.service.SalesOrderService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.yupi.springbootinit.service.workflow.WorkflowTaskConstants.*;

/**
 * 工作流任务创建服务
 */
@Slf4j
@Service
public class WorkflowTaskCreationService {

    @Resource
    private WorkflowTaskMapper workflowTaskMapper;

    @Resource
    private SalesOrderMapper salesOrderMapper;

    @Resource
    private ProcessSheetMapper processSheetMapper;

    @Resource
    private ProcessBatchStepMapper processBatchStepMapper;

    @Resource
    private SalesOrderItemMapper salesOrderItemMapper;

    @Resource
    private ProcessBatchMapper processBatchMapper;

    @Resource
    private OutboxService outboxService;

    @Resource
    private SalesOrderService salesOrderService;

    @Resource
    private MessageCenterProperties messageCenterProperties;

    @Resource
    private WorkflowTaskUtils workflowTaskUtils;

    // ==================== 原有方法保持不变 ====================

    /**
     * 为销售订单创建工程部待办：创建工艺单
     */
    public void createProcessSheetTaskForSalesOrder(Long salesOrderId, String orderNumber, String productName,
                                                    Long creatorId, String creatorName) {
        createTaskForSalesOrder(
                salesOrderId, orderNumber, productName, creatorId, creatorName,
                ENG_DEPT_CODE, "创建工艺单", "销售订单待创建工艺单",
                TASK_TYPE_CREATE_PROCESS_SHEET, "创建工程部待办"
        );
    }

    /**
     * 清机完成后为批次创建生产工单任务（不拆分工序）
     */
    public void createProductionWorkorderTaskForBatch(Long batchId, String orderNumber, String productName,
                                                      Long creatorId, String creatorName) {
        Department dept = workflowTaskUtils.getDepartmentByCode(PROD_DEPT_CODE);
        if (dept == null || batchId == null) {
            log.warn("创建生产工单任务失败: dept or batchId null. dept={}, batchId={}", dept, batchId);
            return;
        }

        // 查询批次信息
        ProcessBatch batch = processBatchMapper.selectById(batchId);
        if (batch == null || (batch.getIsDeleted() != null && batch.getIsDeleted() == 1)) {
            log.warn("创建生产工单任务失败：批次不存在或已删除, batchId={}", batchId);
            return;
        }

        WorkflowTask task = new WorkflowTask();
        task.setTaskTitle("生产执行");

        // 【修改】描述中显式包含：批次号、流程卡编号、生产计划号、产品信息
        StringBuilder descBuilder = new StringBuilder();
        String batchInfo = StringUtils.defaultString(batch.getBatchCode(), "待生成");
        descBuilder.append("批次号：").append(batchInfo);
        if (StringUtils.isNotBlank(batch.getFlowNumber())) {
            descBuilder.append(" | 流程卡编号：").append(batch.getFlowNumber());
        }
        if (StringUtils.isNotBlank(batch.getProductionPlanNumber())) {
            descBuilder.append(" | 生产计划号：").append(batch.getProductionPlanNumber());
        }
        descBuilder.append(" | 产品：").append(StringUtils.defaultString(productName));
        task.setTaskDescription(descBuilder.toString());

        task.setTaskType("PRODUCTION_WORKORDER");
        task.setBizType(BIZ_TYPE_PROCESS_BATCH);
        task.setBizId(batchId);

        // 【修改】BizNumber 优先使用生产批次号，若无则使用订单号
        if (StringUtils.isNotBlank(batch.getBatchCode())) {
            task.setBizNumber(batch.getBatchCode());
        } else {
            task.setBizNumber(StringUtils.defaultString(orderNumber));
        }

        task.setProductName(StringUtils.defaultString(productName));
        task.setDepartmentId(dept.getId());
        task.setDepartmentName(dept.getDepartmentName());
        task.setTaskStatus(STATUS_PENDING);
        task.setPriority(PRIORITY_NORMAL);
        task.setCreatedBy(creatorId);
        task.setCreatedByName(creatorName);

        // 设置生产计划开始时间
        if (batch.getPlanStart() != null) {
            task.setExpectedCompleteTime(batch.getPlanStart());
        } else {
            log.warn("⚠️ 批次未设置计划开始时间，生产工单无法设置期限: batchId={}", batchId);
        }

        LocalDateTime now = LocalDateTime.now();
        task.setCreateTime(now);
        task.setUpdateTime(now);
        task.setIsDelete(0);

        int rows = workflowTaskMapper.insert(task);
        log.info("创建生产工单任务成功: batchId={}, batchCode={}, taskId={}, rows={}", batchId, batch.getBatchCode(), task.getId(), rows);

        publishTaskEvents(task, batchId);
    }

    /**
     * 🔧 修改：为销售订单创建PMC待办：生产排期（保持向后兼容）
     *
     * @deprecated 建议使用 {@link #getOrCreateScheduleTaskForSalesOrder(Long, String, String, Long, String)}
     */
    public void createScheduleTaskForSalesOrder(Long salesOrderId, String orderNumber, String productName,
                                                Long creatorId, String creatorName) {
        createTaskForSalesOrder(
                salesOrderId, orderNumber, productName, creatorId, creatorName,
                PMC_DEPT_CODE, "生产排期", "销售订单待生产排期",
                TASK_TYPE_CREATE_SCHEDULE, "创建PMC待办"
        );
    }

    /**
     * 🔧 新增：获取或创建PMC排期父任务（防重复创建）
     *
     * @return 父任务ID（可能是已存在的，也可能是新创建的）
     */
    public Long getOrCreateScheduleTaskForSalesOrder(Long salesOrderId, String orderNumber, String productName,
                                                     Long creatorId, String creatorName) {
        if (salesOrderId == null) {
            log.warn("获取或创建PMC排期任务失败：salesOrderId 为空");
            return null;
        }

        log.info("========== 开始获取或创建PMC排期父任务 ==========");
        log.info("salesOrderId={}, orderNumber={}", salesOrderId, orderNumber);

        // ========== 1. 先查询是否已存在父任务 ==========
        WorkflowTask existingTask = workflowTaskMapper.selectOne(
                new QueryWrapper<WorkflowTask>()
                        .eq("bizType", BIZ_TYPE_SALES_ORDER)
                        .eq("bizId", salesOrderId)
                        .eq("taskType", TASK_TYPE_CREATE_SCHEDULE)
                        .eq("isDelete", 0)
                        .isNull("parentTaskId")
                        .in("taskStatus", Arrays.asList(STATUS_PENDING, STATUS_IN_PROGRESS))
                        .orderByDesc("createTime")
                        .last("LIMIT 1")
        );

        if (existingTask != null) {
            log.info("✅ 复用已存在的PMC排期父任务: taskId={}, salesOrderId={}, status={}",
                    existingTask.getId(), salesOrderId, existingTask.getTaskStatus());
            return existingTask.getId();
        }

        // ========== 2. 不存在则创建新任务 ==========
        log.info("未找到已存在的父任务，开始创建新的父任务");

        createScheduleTaskForSalesOrder(salesOrderId, orderNumber, productName, creatorId, creatorName);

        // ========== 3. 查询刚创建的任务 ==========
        WorkflowTask newTask = workflowTaskMapper.selectOne(
                new QueryWrapper<WorkflowTask>()
                        .eq("bizType", BIZ_TYPE_SALES_ORDER)
                        .eq("bizId", salesOrderId)
                        .eq("taskType", TASK_TYPE_CREATE_SCHEDULE)
                        .eq("isDelete", 0)
                        .isNull("parentTaskId")  // 🔧 确保是父任务
                        .orderByDesc("create_time")
                        .last("LIMIT 1")
        );

        if (newTask == null) {
            log.error("❌ 创建PMC排期父任务后未能查询到: salesOrderId={}", salesOrderId);
            return null;
        }

        log.info("✅ PMC排期父任务创建成功: taskId={}, salesOrderId={}", newTask.getId(), salesOrderId);
        return newTask.getId();
    }

    /**
     * 🔧 修复：为批次创建发布待办（增加防重检查和认领逻辑优化）
     *
     * @param batchId 批次ID
     * @param orderNumber 订单号
     * @param batchCode 批次编码
     * @param parentTaskId 父任务ID（PMC排期任务ID）
     * @param creatorId 创建人ID
     * @param creatorName 创建人姓名
     */
    public void createPublishBatchTaskForBatch(Long batchId, String orderNumber, String batchCode,
                                               Long parentTaskId, Long creatorId, String creatorName) {
        if (batchId == null) {
            log.warn("创建批次发布待办失败: batchId 为空");
            return;
        }

        log.info("========== 开始创建批次发布子任务 ==========");
        log.info("batchId={}, batchCode={}, parentTaskId={}", batchId, batchCode, parentTaskId);

        // ========== 🔧 修改点1：防重检查 ==========
        Long existingCount = workflowTaskMapper.selectCount(
                new LambdaQueryWrapper<WorkflowTask>()
                        .eq(WorkflowTask::getTaskType, TASK_TYPE_PUBLISH_BATCH)
                        .eq(WorkflowTask::getBizType, BIZ_TYPE_PROCESS_BATCH).eq(WorkflowTask::getBizId, batchId).eq(WorkflowTask::getParentTaskId, parentTaskId)
                        .eq(WorkflowTask::getIsDelete, 0)
        );

        if (existingCount != null && existingCount > 0) {
            log.info("✅ 批次发布任务已存在，跳过创建: batchId={}, parentTaskId={}, count={}",
                    batchId, parentTaskId, existingCount);
            return;
        }

        Department dept = workflowTaskUtils.getDepartmentByCode(PMC_DEPT_CODE);
        if (dept == null) {
            log.error("❌ 创建批次发布待办失败：未找到PMC部门，deptCode={}", PMC_DEPT_CODE);
            return;
        }

        // ========== 🔧 修改点2：查询父任务获取认领人信息 ==========
        Long claimedBy = null;
        String claimedByName = null;
        LocalDateTime claimedTime = null;

        if (parentTaskId != null) {
            WorkflowTask parentTask = workflowTaskMapper.selectById(parentTaskId);
            if (parentTask != null && parentTask.getClaimedBy() != null) {
                claimedBy = parentTask.getClaimedBy();
                claimedByName = parentTask.getClaimedByName();
                claimedTime = LocalDateTime.now();
                log.info("✅ 子任务继承父任务认领人: parentTaskId={}, claimedBy={}, claimedByName={}",
                        parentTaskId, claimedBy, claimedByName);
            } else {
                log.info("⚠️ 父任务未被认领: parentTaskId={}", parentTaskId);
            }
        } else {
            log.warn("⚠️ 未指定父任务ID，子任务不继承认领人");
        }

        // ========== 🔧 修改点3：构建任务对象 ==========
        WorkflowTask task = new WorkflowTask();
        task.setTaskTitle("批次发布");
        task.setTaskDescription("发布批次 - " + StringUtils.defaultString(batchCode, ""));
        task.setTaskType(TASK_TYPE_PUBLISH_BATCH);
        task.setBizType(BIZ_TYPE_PROCESS_BATCH);
        task.setBizId(batchId);
        task.setBizNumber(StringUtils.defaultString(orderNumber));
        task.setProductName(StringUtils.defaultString(batchCode));
        task.setDepartmentId(dept.getId());
        task.setDepartmentName(dept.getDepartmentName());
        task.setParentTaskId(parentTaskId);

        // ========== 🔧 修改点4：状态始终为 PENDING（需要用户手动点击"去完成"） ==========
        task.setTaskStatus(STATUS_PENDING);
        task.setPriority(PRIORITY_NORMAL);

        // ========== 🔧 修改点5：设置认领人信息（但状态仍为 PENDING） ==========
        task.setClaimedBy(claimedBy);
        task.setClaimedByName(claimedByName);
        task.setClaimedTime(claimedTime);

        task.setCreatedBy(creatorId);
        task.setCreatedByName(creatorName);

        LocalDateTime now = LocalDateTime.now();
        task.setCreateTime(now);
        task.setUpdateTime(now);
        task.setIsDelete(0);

        int rows = workflowTaskMapper.insert(task);
        if (rows > 0) {
            log.info("✅ 批次发布子任务创建成功: taskId={}, batchId={}, batchCode={}, " +
                            "parentTaskId={}, claimedBy={}, status={}",
                    task.getId(), batchId, batchCode, parentTaskId, claimedBy, task.getTaskStatus());

            publishTaskEvents(task, batchId);
        } else {
            log.error("❌ 批次发布子任务创建失败: batchId={}, rows={}", batchId, rows);
        }

        log.info("========== 批次发布子任务创建流程结束 ==========");
    }

    /**
     * 为生产部创建生产准备任务（如清机），部门编码 SC001
     */
    public void createProductionPrepTaskForBatch(Long batchId,
                                                 String orderNumber,
                                                 String productName,
                                                 String taskType,
                                                 Long creatorId,
                                                 String creatorName) {
        if (batchId == null) {
            log.warn("创建生产准备任务失败：batchId为空");
            return;
        }
        Department dept = workflowTaskUtils.getDepartmentByCode(PROD_DEPT_CODE);
        if (dept == null) {
            log.error("创建生产准备任务失败：未找到生产部，deptCode={}", PROD_DEPT_CODE);
            return;
        }

        // ========== ✅ 新增：查询批次信息，用于设置期限 ==========
        ProcessBatch batch = processBatchMapper.selectById(batchId);
        if (batch == null || batch.getIsDeleted() != null && batch.getIsDeleted() == 1) {
            log.warn("创建生产准备任务失败：批次不存在或已删除, batchId={}", batchId);
            return;
        }

        WorkflowTask task = new WorkflowTask();
        task.setTaskTitle("生产准备-清机");
        
        // 【修改】任务描述包含：订单号、批次号、产品信息、生产设备、材料信息
        StringBuilder descBuilder = new StringBuilder();
        descBuilder.append("订单：").append(StringUtils.defaultString(orderNumber));
        if (StringUtils.isNotBlank(batch.getBatchCode())) {
            descBuilder.append(" | 批次号：").append(batch.getBatchCode());
        }
        descBuilder.append(" | 产品：").append(StringUtils.defaultString(productName));
        if (StringUtils.isNotBlank(batch.getDeviceName())) {
            descBuilder.append(" | 生产设备：").append(batch.getDeviceName());
        }
        if (StringUtils.isNotBlank(batch.getPowderModel())) {
            descBuilder.append(" | 粉末型号：").append(batch.getPowderModel());
        }
        if (batch.getPowderWeight() != null) {
            descBuilder.append(" | 粉末重量：").append(batch.getPowderWeight()).append("g");
        }
        task.setTaskDescription(descBuilder.toString());
        
        task.setTaskType(StringUtils.defaultIfBlank(taskType, "PRODUCTION_PREP_CLEANING"));
        task.setBizType(BIZ_TYPE_PROCESS_BATCH);
        task.setBizId(batchId);
        // 【修改】BizNumber 优先使用批次号，若无则使用订单号
        if (StringUtils.isNotBlank(batch.getBatchCode())) {
            task.setBizNumber(batch.getBatchCode());
        } else {
            task.setBizNumber(StringUtils.defaultString(orderNumber));
        }
        task.setProductName(StringUtils.defaultString(productName));
        task.setDepartmentId(dept.getId());
        task.setDepartmentName(dept.getDepartmentName());
        task.setTaskStatus(STATUS_PENDING);
        task.setPriority(PRIORITY_NORMAL);
        task.setCreatedBy(creatorId);
        task.setCreatedByName(creatorName);

        // ========== ✅ 关键修复：设置逾期时间 ==========
        if (batch.getPlanStart() != null) {
            // 清机必须在生产开始前 2 小时完成
            LocalDateTime expectedTime = batch.getPlanStart().minusHours(2);
            task.setExpectedCompleteTime(expectedTime);

            log.info("设置清机任务期限: batchId={}, planStart={}, expectedCompleteTime={}",
                    batchId, batch.getPlanStart(), expectedTime);
        } else {
            log.warn("⚠️ 批次未设置计划开始时间，清机任务无法设置期限: batchId={}", batchId);
        }

        LocalDateTime now = LocalDateTime.now();
        task.setCreateTime(now);
        task.setUpdateTime(now);
        task.setIsDelete(0);

        int rows = workflowTaskMapper.insert(task);
        log.info("创建生产部任务: type={}, bizType={}, bizId={}, deptId={}, expectedCompleteTime={}, rows={}",
                task.getTaskType(), BIZ_TYPE_PROCESS_BATCH, batchId, dept.getId(), task.getExpectedCompleteTime(), rows);

        publishTaskEvents(task, batchId);
    }

    // ==================== ✅ 新增：质检任务创建 ====================

    /**
     * 为质检部创建工序检验任务
     *
     * @param batchStepId 批次工序ID
     * @param batchId 批次ID
     * @param orderNumber 订单编号
     * @param stepName 工序名称
     * @param stepNo 工序序号
     * @param creatorId 创建人ID（通常是完成该工序的操作员）
     * @param creatorName 创建人姓名
     */
    public void createQualityInspectionTask(Long batchStepId, Long batchId,
                                            String orderNumber, String stepName, Integer stepNo,
                                            Long creatorId, String creatorName) {
        if (batchStepId == null) {
            log.warn("创建质检任务失败：batchStepId为空");
            return;
        }

        // 🔧 防重检查（已有）
        Long existingCount = workflowTaskMapper.selectCount(
                new LambdaQueryWrapper<WorkflowTask>()
                        .eq(WorkflowTask::getTaskType, "QUALITY_INSPECTION")
                        .eq(WorkflowTask::getBizType, "PROCESS_BATCH_STEP")
                        .eq(WorkflowTask::getBizId, batchStepId)
                        .eq(WorkflowTask::getIsDelete, 0)
        );

        if (existingCount != null && existingCount > 0) {
            log.info("质检任务已存在，跳过创建: stepId={}, count={}", batchStepId, existingCount);
            return;
        }

        // 获取质检部门信息
        Department dept = workflowTaskUtils.getDepartmentByCode("PZ001"); // 品质部门编码
        if (dept == null) {
            log.error("创建质检任务失败：未找到品质部门，deptCode=PZ001");
            return;
        }

        // 获取工序详细信息（用于设置任务优先级和期限）
        ProcessBatchStep step = processBatchStepMapper.selectById(batchStepId);
        LocalDateTime expectedCompleteTime = null;
        String priority = PRIORITY_NORMAL;

        if (step != null) {
            // 质检期限 = 工序完成时间 + 2小时（可配置）
            if (step.getActualEnd() != null) {
                expectedCompleteTime = step.getActualEnd().plusHours(2);
            } else if (step.getPlanEnd() != null) {
                expectedCompleteTime = step.getPlanEnd().plusHours(2);
            }

            // 根据工序优先级设置质检优先级
            if (step.getPlanEnd() != null && step.getPlanEnd().isBefore(LocalDateTime.now().plusHours(4))) {
                priority = PRIORITY_URGENT; // 计划完成时间紧急的工序，质检优先级设为紧急
            }
        }

        // 构建任务对象
        WorkflowTask task = new WorkflowTask();
        task.setTaskTitle("工序质检");
        task.setTaskDescription(String.format("检验工序 [%s] %s",
                stepNo != null ? "第" + stepNo + "道" : "",
                StringUtils.defaultString(stepName, "未知工序")));
        task.setTaskType("QUALITY_INSPECTION");
        task.setBizType("PROCESS_BATCH_STEP");
        task.setBizId(batchStepId);
        task.setBizNumber(StringUtils.defaultString(orderNumber));
        task.setProductName(stepName); // 复用productName字段存储工序名称
        task.setDepartmentId(dept.getId());
        task.setDepartmentName(dept.getDepartmentName());
        task.setTaskStatus(STATUS_PENDING);
        task.setPriority(priority);
        task.setExpectedCompleteTime(expectedCompleteTime);
        task.setCreatedBy(creatorId);
        task.setCreatedByName(creatorName);

        LocalDateTime now = LocalDateTime.now();
        task.setCreateTime(now);
        task.setUpdateTime(now);
        task.setIsDelete(0);

        // 保存任务
        int rows = workflowTaskMapper.insert(task);
        if (rows > 0) {
            log.info("创建质检任务成功: stepId={}, taskId={}, stepName={}, priority={}",
                    batchStepId, task.getId(), stepName, priority);

            // 发布任务事件
            publishTaskEvents(task, batchStepId);
        } else {
            log.error("创建质检任务失败: stepId={}, rows={}", batchStepId, rows);
        }
    }

    /**
     * ✅ 新增：为生产部创建返工任务
     *
     * @param batchStepId 批次工序ID
     * @param batchId 批次ID
     * @param orderNumber 订单编号
     * @param stepName 工序名称
     * @param failReason 质检不通过原因
     * @param creatorId 创建人ID（质检员）
     * @param creatorName 创建人姓名
     */
    public void createReworkTask(Long batchStepId, Long batchId,
                                 String orderNumber, String stepName, String failReason,
                                 Long creatorId, String creatorName) {
        if (batchStepId == null) {
            log.warn("创建返工任务失败：batchStepId为空");
            return;
        }

        Department dept = workflowTaskUtils.getDepartmentByCode(PROD_DEPT_CODE);
        if (dept == null) {
            log.error("创建返工任务失败：未找到生产部门，deptCode={}", PROD_DEPT_CODE);
            return;
        }

        WorkflowTask task = new WorkflowTask();
        task.setTaskTitle("工序返工");
        task.setTaskDescription(String.format("工序 [%s] 质检不合格，需返工。原因：%s",
                StringUtils.defaultString(stepName, "未知工序"),
                StringUtils.defaultString(failReason, "未填写")));
        task.setTaskType("PRODUCTION_REWORK");
        task.setBizType("PROCESS_BATCH_STEP");
        task.setBizId(batchStepId);
        task.setBizNumber(StringUtils.defaultString(orderNumber));
        task.setProductName(stepName);
        task.setDepartmentId(dept.getId());
        task.setDepartmentName(dept.getDepartmentName());
        task.setTaskStatus(STATUS_PENDING);
        task.setPriority(PRIORITY_URGENT); // 返工任务优先级设为紧急
        task.setCreatedBy(creatorId);
        task.setCreatedByName(creatorName);

        LocalDateTime now = LocalDateTime.now();
        task.setCreateTime(now);
        task.setUpdateTime(now);
        task.setIsDelete(0);

        int rows = workflowTaskMapper.insert(task);
        if (rows > 0) {
            log.info("创建返工任务成功: stepId={}, taskId={}, reason={}",
                    batchStepId, task.getId(), failReason);
            publishTaskEvents(task, batchStepId);
        } else {
            log.error("创建返工任务失败: stepId={}, rows={}", batchStepId, rows);
        }
    }

    /**
     * ✅ 为质检部创建检验报告生成任务
     *
     * 触发时机：当工艺单的所有批次的所有工序都完成后
     *
     * @param processSheetId 工艺单ID（一个工艺单对应一个检验报告）
     * @param orderNumber 订单编号
     * @param productName 产品名称
     * @param creatorId 创建人ID（生产员或质检员）
     * @param creatorName 创建人姓名
     */
    public void createInspectionReportTask(Long processSheetId,
                                           String orderNumber,
                                           String productName,
                                           Long creatorId,
                                           String creatorName) {
        if (processSheetId == null) {
            log.warn("创建检验报告任务失败：processSheetId为空");
            return;
        }

        log.info("========== 开始创建检验报告任务 ==========");
        log.info("processSheetId={}, orderNumber={}, productName={}, creator={}",
                processSheetId, orderNumber, productName, creatorName);

        // ========== 1. 防重：检查是否已存在该工艺单的检验报告任务 ==========
        Long existingCount = workflowTaskMapper.selectCount(
                new LambdaQueryWrapper<WorkflowTask>()
                        .eq(WorkflowTask::getTaskType, "GENERATE_INSPECTION_REPORT")
                        .eq(WorkflowTask::getBizType, "PROCESS_SHEET")
                        .eq(WorkflowTask::getBizId, processSheetId).eq(WorkflowTask::getIsDelete, 0).in(WorkflowTask::getTaskStatus, Arrays.asList("PENDING", "IN_PROGRESS", "DONE"))
        );

        if (existingCount != null && existingCount > 0) {
            log.info("✅ 检验报告任务已存在，跳过创建: processSheetId={}, count={}", processSheetId, existingCount);
            return;
        }

        // ========== 2. ✅ 查询批次信息 ==========
        List<ProcessBatch> batchList = processBatchMapper.selectList(
                new LambdaQueryWrapper<ProcessBatch>()
                        .eq(ProcessBatch::getProcessSheetId, processSheetId)
                        .eq(ProcessBatch::getIsDeleted, 0)
        );

        if (batchList == null || batchList.isEmpty()) {
            log.warn("⚠️ 创建检验报告任务失败：未找到批次, processSheetId={}", processSheetId);
            return;
        }

        log.info("工艺单批次信息: processSheetId={}, 总批次数={}", processSheetId, batchList.size());

        // ========== 3. ✅ 检查每个批次的所有工序是否都完成 ==========
        for (ProcessBatch batch : batchList) {
            // 查询该批次的所有工序状态
            List<ProcessBatchStep> steps = processBatchStepMapper.selectList(
                    new LambdaQueryWrapper<ProcessBatchStep>()
                            .eq(ProcessBatchStep::getBatchId, batch.getId())
                            .eq(ProcessBatchStep::getIsDeleted, 0)
            );

            if (steps == null || steps.isEmpty()) {
                log.warn("⚠️ 批次无工序数据: batchId={}, batchCode={}", batch.getId(), batch.getBatchCode());
                return;
            }

            long incompleteCount = steps.stream()
                    .filter(s -> !"COMPLETED".equals(s.getStatus()))
                    .count();

            if (incompleteCount > 0) {
                log.warn("⚠️ 批次仍有未完成工序，不能创建检验报告: batchId={}, batchCode={}, " +
                                "总工序={}, 未完成工序={}",
                        batch.getId(), batch.getBatchCode(), steps.size(), incompleteCount);
                return;
            }
        }

        log.info("✅ 二次校验通过：所有批次的所有工序都已完成, processSheetId={}, 批次数={}",
                processSheetId, batchList.size());

        // ========== 4. ✅ 收集扩展信息（用于存储在 remark 中）==========
        Map<String, Object> extendedInfo = new HashMap<>();

        try {
            // 查询工艺单信息
            ProcessSheet processSheet = processSheetMapper.selectById(processSheetId);
            if (processSheet != null) {
                extendedInfo.put("productCode", processSheet.getProductCode());

                // ✅ 计算总数量
                int totalQuantity = batchList.stream()
                        .mapToInt(b -> b.getQuantity() != null ? b.getQuantity() : 0)
                        .sum();
                extendedInfo.put("quantity", totalQuantity);
                extendedInfo.put("batchCount", batchList.size());

                // ✅ 查询订单信息（获取规格型号、客户名称等）
                if (processSheet.getSourceType() != null && processSheet.getSourceType() == 1
                        && processSheet.getSourceId() != null) {
                    try {
                        // 查询订单主表
                        SalesOrder salesOrder = salesOrderMapper.selectById(processSheet.getSourceId());
                        if (salesOrder != null) {
                            extendedInfo.put("customerName", salesOrder.getCustomerName());
                            extendedInfo.put("orderNumber", salesOrder.getOrderNumber());

                            // 更新订单号
                            if (StringUtils.isNotBlank(salesOrder.getOrderNumber())) {
                                orderNumber = salesOrder.getOrderNumber();
                            }

                            // ✅ 查询订单明细（获取产品信息）
                            List<SalesOrderItem> orderItems = salesOrderItemMapper.selectList(
                                    new LambdaQueryWrapper<SalesOrderItem>()
                                            .eq(SalesOrderItem::getOrderId, salesOrder.getId())
                                            .eq(SalesOrderItem::getIsDeleted, 0)
                                            .orderByAsc(SalesOrderItem::getSortOrder)
                            );

                            if (orderItems != null && !orderItems.isEmpty()) {
                                // 使用第一个产品的信息
                                SalesOrderItem firstItem = orderItems.get(0);

                                // 更新产品名称
                                if (StringUtils.isNotBlank(firstItem.getProductName())) {
                                    productName = firstItem.getProductName();
                                }

                                // 保存规格型号
                                if (StringUtils.isNotBlank(firstItem.getSpecification())) {
                                    extendedInfo.put("specification", firstItem.getSpecification());
                                }

                                // 保存产品料号
                                if (StringUtils.isNotBlank(firstItem.getProductCode())) {
                                    extendedInfo.put("productCode", firstItem.getProductCode());
                                }

                                // 如果是多产品订单，记录产品数量
                                if (orderItems.size() > 1) {
                                    extendedInfo.put("productCount", orderItems.size());
                                    extendedInfo.put("isMultiProduct", true);

                                    // 可选：记录所有产品名称
                                    List<String> productNames = orderItems.stream()
                                            .map(SalesOrderItem::getProductName)
                                            .filter(StringUtils::isNotBlank)
                                            .collect(Collectors.toList());
                                    extendedInfo.put("allProductNames", productNames);

                                    log.info("✅ 多产品订单: orderId={}, 产品数量={}, 产品列表={}",
                                            salesOrder.getId(), orderItems.size(), productNames);
                                } else {
                                    extendedInfo.put("isMultiProduct", false);
                                }

                                log.info("✅ 产品信息获取成功: productName={}, productCode={}, specification={}",
                                        productName, firstItem.getProductCode(), firstItem.getSpecification());
                            } else {
                                log.warn("⚠️ 订单无明细数据: orderId={}", salesOrder.getId());
                            }
                        }
                    } catch (Exception e) {
                        log.warn("查询销售订单信息失败: orderId={}", processSheet.getSourceId(), e);
                    }
                }
            }

            log.info("✅ 扩展信息收集完成: {}", extendedInfo);

        } catch (Exception e) {
            log.error("❌ 收集扩展信息失败: processSheetId={}", processSheetId, e);
        }

        // ========== 5. 获取质检部门 ==========
        Department dept = workflowTaskUtils.getDepartmentByCode("PZ001");
        if (dept == null) {
            log.error("❌ 创建检验报告任务失败：未找到品质部门，deptCode=PZ001");
            return;
        }

        // ========== 6. 计算期限和优先级 ==========
        ProcessBatch lastBatch = batchList.stream()
                .filter(b -> b.getPlanEnd() != null)
                .max(Comparator.comparing(ProcessBatch::getPlanEnd))
                .orElse(null);

        LocalDateTime expectedCompleteTime = null;
        String priority = PRIORITY_NORMAL;
        LocalDateTime now = LocalDateTime.now();

        if (lastBatch != null && lastBatch.getPlanEnd() != null) {
            expectedCompleteTime = lastBatch.getPlanEnd().plusDays(1);
            if (now.isAfter(lastBatch.getPlanEnd())) {
                priority = PRIORITY_URGENT;
                log.warn("⚠️ 批次已逾期完成，检验报告任务优先级设为紧急: lastBatchId={}, planEnd={}, now={}",
                        lastBatch.getId(), lastBatch.getPlanEnd(), now);
            }
        }

        // ========== 7. ✅ 构建任务对象 ==========
        WorkflowTask task = new WorkflowTask();
        task.setTaskTitle("生成检验报告");
        task.setTaskDescription(String.format("订单 [%s] 的全部 %d 个批次已完成质检，请生成最终检验报告",
                StringUtils.defaultString(orderNumber, "未知订单"),
                batchList.size()));
        task.setTaskType("GENERATE_INSPECTION_REPORT");
        task.setBizType("PROCESS_SHEET");
        task.setBizId(processSheetId);
        task.setBizNumber(StringUtils.defaultString(orderNumber));
        task.setProductName(productName);
        task.setDepartmentId(dept.getId());
        task.setDepartmentName(dept.getDepartmentName());
        task.setTaskStatus(STATUS_PENDING);
        task.setPriority(priority);
        task.setExpectedCompleteTime(expectedCompleteTime);
        task.setCreatedBy(creatorId);
        task.setCreatedByName(creatorName);

        // ✅ 将扩展信息存储在 remark 字段（JSON格式）
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new com.fasterxml.jackson.datatype.jsr310.JavaTimeModule());
            String extInfoJson = mapper.writeValueAsString(extendedInfo);
            task.setRemark(extInfoJson);

            log.info("✅ 扩展信息已存入 remark: processSheetId={}, remark={}", processSheetId, extInfoJson);
        } catch (Exception e) {
            log.warn("⚠️ 序列化扩展信息失败", e);
            task.setRemark("扩展信息序列化失败");
        }

        task.setCreateTime(now);
        task.setUpdateTime(now);
        task.setIsDelete(0);

        // ========== 8. 保存任务 ==========
        int rows = workflowTaskMapper.insert(task);
        if (rows > 0) {
            log.info("✅ 检验报告任务创建成功: processSheetId={}, taskId={}, orderNumber={}, " +
                            "批次数={}, priority={}, expectedCompleteTime={}",
                    processSheetId, task.getId(), orderNumber, batchList.size(), priority, expectedCompleteTime);

            // 9. 发布任务事件
            publishTaskEvents(task, processSheetId);
        } else {
            log.error("❌ 检验报告任务创建失败: processSheetId={}, rows={}", processSheetId, rows);
        }

        log.info("========== 检验报告任务创建流程结束 ==========");
    }


    public void createFinalInspectionReportTask(Long orderId, String orderNumber, String productName,
                                                Long creatorId, String creatorName) {
        if (orderId == null) {
            log.warn("创建最终检验报告任务失败：orderId 为空");
            return;
        }

        log.info("开始创建最终检验报告任务: orderId={}, orderNumber={}", orderId, orderNumber);

        Long existingCount = workflowTaskMapper.selectCount(
                new LambdaQueryWrapper<WorkflowTask>()
                        .eq(WorkflowTask::getTaskType, "FINAL_INSPECTION_REPORT")
                        .eq(WorkflowTask::getBizType, BIZ_TYPE_SALES_ORDER)
                        .eq(WorkflowTask::getBizId, orderId)
                        .eq(WorkflowTask::getIsDelete, 0)
        );

        if (existingCount != null && existingCount > 0) {
            log.info("最终检验报告任务已存在，跳过创建: orderId={}", orderId);
            return;
        }

        ProcessSheet processSheet = processSheetMapper.selectOne(
                new LambdaQueryWrapper<ProcessSheet>()
                        .eq(ProcessSheet::getSourceType, 1)
                        .eq(ProcessSheet::getSourceId, orderId)
                        .eq(ProcessSheet::getIsDeleted, 0)
                        .last("LIMIT 1")
        );

        if (processSheet == null) {
            log.warn("未找到订单对应的工艺单，无法创建检验报告任务: orderId={}", orderId);
            return;
        }

        List<ProcessBatch> batches = processBatchMapper.selectList(
                new LambdaQueryWrapper<ProcessBatch>()
                        .eq(ProcessBatch::getProcessSheetId, processSheet.getId())
                        .eq(ProcessBatch::getIsDeleted, 0)
        );

        if (batches == null || batches.isEmpty()) {
            log.warn("工艺单无批次数据，无法创建检验报告任务: processSheetId={}", processSheet.getId());
            return;
        }

        long incompleteCount = batches.stream()
                .filter(b -> !"COMPLETED".equals(b.getStatus()))
                .count();

        if (incompleteCount > 0) {
            log.warn("仍有未完成批次，暂不创建检验报告任务: orderId={}, 总批次={}, 未完成={}",
                    orderId, batches.size(), incompleteCount);
            return;
        }

        log.info("所有批次已完成，创建最终检验报告任务: orderId={}, 批次数={}", orderId, batches.size());

        Department qaDept = workflowTaskUtils.getDepartmentByCode("PZ001");
        if (qaDept == null) {
            log.error("创建最终检验报告任务失败：未找到品质部门，deptCode=PZ001");
            return;
        }

        WorkflowTask task = new WorkflowTask();
        task.setTaskTitle("生成最终检验报告");
        task.setTaskDescription(String.format("订单 [%s] 的全部 %d 个批次已完成，请生成最终检验报告",
                StringUtils.defaultString(orderNumber, "未知订单"),
                batches.size()));
        task.setTaskType("FINAL_INSPECTION_REPORT");
        task.setBizType(BIZ_TYPE_SALES_ORDER);
        task.setBizId(orderId);
        task.setBizNumber(orderNumber);
        task.setProductName(productName);
        task.setDepartmentId(qaDept.getId());
        task.setDepartmentName(qaDept.getDepartmentName());
        task.setTaskStatus(STATUS_PENDING);
        task.setPriority(PRIORITY_NORMAL);
        task.setCreatedBy(creatorId);
        task.setCreatedByName(creatorName);

        LocalDateTime now = LocalDateTime.now();
        task.setCreateTime(now);
        task.setUpdateTime(now);
        task.setIsDelete(0);

        int rows = workflowTaskMapper.insert(task);
        if (rows > 0) {
            log.info("最终检验报告任务创建成功: taskId={}, orderId={}, orderNumber={}, 批次数={}",
                    task.getId(), orderId, orderNumber, batches.size());
            publishTaskEvents(task, orderId);
        } else {
            log.error("最终检验报告任务创建失败: orderId={}, rows={}", orderId, rows);
        }
    }
    // ==================== 私有辅助方法 ====================

    /**
     * 通用任务创建方法（抽取重复代码）
     */
    private void createTaskForSalesOrder(Long salesOrderId, String orderNumber, String productName,
                                         Long creatorId, String creatorName, String deptCode,
                                         String taskTitle, String taskDescPrefix, String taskType, String logMessage) {
        if (salesOrderId == null) {
            log.warn("{}失败：salesOrderId 为空", logMessage);
            return;
        }

        Department dept = workflowTaskUtils.getDepartmentByCode(deptCode);
        if (dept == null) {
            log.error("{}失败：未找到部门，deptCode={}", logMessage, deptCode);
            return;
        }

        // 根据订单紧急程度设置任务优先级
        String taskPriority = PRIORITY_NORMAL;
        try {
            SalesOrder order = salesOrderService.getById(salesOrderId);
            String urgency = order == null ? null : order.getUrgencyLevel();
            if (StringUtils.isNotBlank(urgency)) {
                switch (urgency.toUpperCase()) {
                    case "URGENT":
                        taskPriority = PRIORITY_URGENT;
                        break;
                    case "NORMAL":
                        taskPriority = PRIORITY_NORMAL;
                        break;
                    case "LOW":
                        taskPriority = PRIORITY_NORMAL;
                        break;
                    default:
                        taskPriority = PRIORITY_NORMAL;
                }
            }
        } catch (Exception e) {
            log.warn("获取订单紧急程度失败，使用默认优先级: orderId={}", salesOrderId, e);
        }

        WorkflowTask task = buildWorkflowTask(salesOrderId, orderNumber, productName, creatorId, creatorName,
                dept, taskTitle, taskDescPrefix, taskType);
        task.setPriority(taskPriority);

        int rows = workflowTaskMapper.insert(task);
        log.info("{}: type={}, bizType={}, bizId={}, productName={}, rows={}",
                logMessage, taskType, BIZ_TYPE_SALES_ORDER, salesOrderId, productName, rows);

        publishTaskEvents(task, salesOrderId);
    }

    /**
     * 构建 WorkflowTask 实体对象
     */
    private WorkflowTask buildWorkflowTask(Long salesOrderId, String orderNumber, String productName,
                                           Long creatorId, String creatorName, Department dept,
                                           String taskTitle, String taskDescPrefix, String taskType) {
        WorkflowTask task = new WorkflowTask();
        task.setTaskTitle(taskTitle);
        task.setTaskDescription(taskDescPrefix + " - " + Objects.toString(productName, ""));
        task.setTaskType(taskType);
        task.setBizType(BIZ_TYPE_SALES_ORDER);
        task.setBizId(salesOrderId);
        task.setBizNumber(StringUtils.defaultString(orderNumber));
        task.setProductName(StringUtils.defaultString(productName));
        task.setDepartmentId(dept.getId());
        task.setDepartmentName(dept.getDepartmentName());
        task.setTaskStatus(STATUS_PENDING);
        task.setPriority(PRIORITY_NORMAL);
        task.setCreatedBy(creatorId);
        task.setCreatedByName(creatorName);

        LocalDateTime now = LocalDateTime.now();
        task.setCreateTime(now);
        task.setUpdateTime(now);
        task.setIsDelete(0);

        return task;
    }

    /**
     * 发布任务相关事件
     */
    private void publishTaskEvents(WorkflowTask task, Long bizId) {
        log.debug("任务创建完成: taskId={}, taskType={}, bizId={}", task.getId(), task.getTaskType(), bizId);
    }

}